/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package networkresourcescanner;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Enumeration;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

/**
 *
 * @author hirayami
 */
public class MyTree extends JTree implements MouseListener, ActionListener {

    public int maxThread;
    public int runningThreadCount;
    private Thread currentRunningThread;
    public Boolean isScannerThreadSleeping;
    private String name;
    DefaultMutableTreeNode rootNode;
    MyTreeNode[] IPNode;

    public MyTree() {
        super();
        initTree("Network Resources");
    }

    public MyTree(String name) {
        super();
        initTree(name);
    }

    private void initTree(String name) {
        rootNode = new DefaultMutableTreeNode(this.name = name);
        ((DefaultTreeModel) this.getModel()).setRoot(rootNode);
        this.addMouseListener(this);
    }

    public void addNode(MyTreeNode mtn) {
        ((DefaultTreeModel) this.getModel()).insertNodeInto(mtn, rootNode, rootNode.getChildCount());
    }

    public void removeNode(MyTreeNode mtn) {
        ((DefaultTreeModel) this.getModel()).removeNodeFromParent(mtn);
    }

    public void removeAllNode() {
        rootNode = new DefaultMutableTreeNode(name);
        ((DefaultTreeModel) this.getModel()).setRoot(rootNode);
        //W.P("Removed all nodes");
    }

    public void expandAllNode() {
        expandNode(new TreePath(rootNode));
    }

    private void expandNode(TreePath parent) {
        TreeNode node = (TreeNode) parent.getLastPathComponent();
        if (node.getChildCount() >= 0) {
            for (Enumeration e = node.children(); e.hasMoreElements();) {
                TreeNode n = (TreeNode) e.nextElement();
                TreePath path = parent.pathByAddingChild(n);
                expandNode(path);
            }
        }
        this.expandPath(parent);
    }

    public void filterByShare() {
        int i;
        for (i = rootNode.getChildCount() - 1; i >= 0; i--) {
            MyTreeNode child = (MyTreeNode) rootNode.getChildAt(i);
            if (child.isScanCompleted && child.getChildCount() <= 0) {
                removeNode(child);
                //            child.
            }
        }
    }

    public void startScanning(final String[] ipStrings, int maxThread) {

        this.maxThread = maxThread;
        this.IPNode = new MyTreeNode[ipStrings.length];


        final MyTree mt = this;
        removeAllNode();
        this.expandPath(new TreePath(rootNode.getPath()));

        currentRunningThread = new Thread() {

            public void run() {
                runningThreadCount = 0;
                isScannerThreadSleeping = false;
                jcifs.Config.registerSmbURLHandler();

                int i;
                for (i = 0; i < ipStrings.length; i++) {
                    if (runningThreadCount < mt.maxThread) {

                        IPNode[i] = new MyTreeNode(ipStrings[i], mt);
                        addNode(IPNode[i]);
                        IPNode[i].startScanning();
                        runningThreadCount++;
                    } else {
                        pauseScanning();
                    }
                }
            }
//            
//            synchronized  void  pause()
//            {
//                try {
//                    if (runningThreadCount >= mt.maxThread) {
//                    this.wait();
//                    }
//                } catch (InterruptedException ex) {
//                    Logger.getLogger(MyTree.class.getName()).log(Level.SEVERE, null, ex);
//                }
//                this.notify();
//            }
//            
        };
        currentRunningThread.start();
    }

    public void pauseScanning() {
        try {
            synchronized (isScannerThreadSleeping) {
                if (!isScannerThreadSleeping) {
                    isScannerThreadSleeping = true;
                    Thread.sleep(99999999);
                }
            }
            //W.P("gone to sleep");
        } catch (Exception ex) {
            //ex.printStackTrace();
            //W.P("____________________________________________________________-Sleep interrupted");
        }
    }

    public void runNextThread() {
        runningThreadCount--;
        resumeScanning();
    }

    public void resumeScanning() {
        //W.P("scan to be resumed:" + runningThreadCount);
        synchronized (isScannerThreadSleeping) {
            if (isScannerThreadSleeping) {
                isScannerThreadSleeping = false;
                currentRunningThread.interrupt();
                //W.P("Scan resumed");
            }
        }
    }

    public void stopScanning() {
        (new Thread() {

            public void run() {
                currentRunningThread.stop();
                int i, l = rootNode.getChildCount();
                for (i = 0; i < l; i++) {
                    ((MyTreeNode) rootNode.getChildAt(i)).stopScanning();
                }
            }
        }).start();
    }

    @Override
    public void mouseClicked(MouseEvent me) {
        MyTreeNode mtn = null;
        if (this.getLastSelectedPathComponent() instanceof MyTreeNode) {
            mtn = (MyTreeNode) this.getLastSelectedPathComponent();
        }

        if (mtn == null) {
            return;
        }

        if (me.getClickCount() == 2) {
            //TODO: These command cna be changed for further issues
            if (mtn.getSmbFile() != null && mtn.isScanCompleted) {
                //W.P(mtn.getSmbFile());
                String comString = "nautilus " + mtn.getSmbFile().toString().replace(" ", "%20");
                //comString = comString.replace(" ", "\\ ");
                W.P(comString);
                W.exec(comString);
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent me) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseReleased(MouseEvent me) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseEntered(MouseEvent me) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseExited(MouseEvent me) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        //throw new UnsupportedOperationException("Not supported yet.");
        W.P("action performed:");

    }
}
